﻿using System;
using System.Collections.Generic;
using System.Data.Entity.Core;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using GroceryPriceBook.Core.Service;
using GroceryPriceBook.Core.ViewModel;
using GroceryPriceBook.Core;
using GroceryPriceBook.Extensions;
using Newtonsoft.Json;
using GroceryPriceBook.Infrastructure;

namespace GroceryPriceBook.Controllers
{
	public class ProductController : BaseController
	{
		readonly ProductHandler _handler = new ProductHandler();
		readonly ProductCategoryHandler _handlerProductCategory = new ProductCategoryHandler();
		readonly ProductAmountUnitHandler _handlerProductAmountUnit = new ProductAmountUnitHandler();
		readonly ProductQuantityUnitHandler _handlerProductQuantityUnit = new ProductQuantityUnitHandler();
		readonly ProductManufacturerHandler _handlerProductManufacturer = new ProductManufacturerHandler();

		#region JSON Methods

		/// <summary>
		/// 
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		[HttpPost]
		public ActionResult DetailsJson(string id)
		{
			var jsonNetResult = new JsonNetResult();
			var response = new List<Object>(3);
			var product = new Product();
			response.Add("success");
			response.Add(product);
			try
			{
				product = _handler.ReadOne(new Guid(id));
				response[1] = product;
			}
			catch (Exception ex)
			{
				response[0] = "error";
				response.Add(ex);
			}

			jsonNetResult.Data = response;
			return jsonNetResult;
		}

		#endregion

		// GET: /Product/
		public ActionResult Index()
		{
			return View(_handler.ReadAll());
		}

		// GET: /Product/Details/5
		public ActionResult Details(Guid? id)
		{
			if (id == null)
			{
				return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
			}
			var product = _handler.ReadOne(id.Value);
			if (product == null)
			{
				return HttpNotFound();
			}
			return View(product);
		}

		// GET: /Product/Create
		public ActionResult Create()
		{
			var product = new Product
						  {
							  ProductAmountUnitSelectListItems =
								  _handlerProductAmountUnit.ReadAll()
														   .ToSelectListItems(amountUnit => amountUnit.Name,
																			  amountUnit => amountUnit.Id.ToString(),
																			  amountUnit => amountUnit.Id == Guid.Empty),
							  ProductQuantityUnitSelectListItems =
								  _handlerProductQuantityUnit.ReadAll()
															 .ToSelectListItems(quantityUnit => quantityUnit.Name,
																				quantityUnit => quantityUnit.Id.ToString(),
																				quantityUnit =>
																				quantityUnit.Id == Guid.Empty),
							  ProductCategorySelectListItems =
								  _handlerProductCategory.ReadAll()
														 .ToSelectListItems(category => category.Name,
																			category => category.Id.ToString(),
																			category => category.Id == Guid.Empty),
							  ProductManufacfurerSelectListItems =
								  _handlerProductManufacturer.ReadAll()
															 .ToSelectListItems(manufacturer => manufacturer.Name,
																				manufacturer => manufacturer.Id.ToString(),
																				manufacturer => manufacturer.Id == Guid.Empty)
						  };

			return View(product);
		}

		// POST: /Product/Create
		// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
		// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
		[HttpPost]
		[ValidateAntiForgeryToken]
		public ActionResult Create([Bind(Include = "Id,IsActive,DateAdded,DateUpdated,Name,ProductManufacturerId,CategoryId,Amount,AmountUnitId,Quantity,QuantityUnitId")] Product product)
		{
			if (!ModelState.IsValid) return View(product);

			if (_handler.Create(ref product) == ServiceResultEnum.Success)
			{
				return RedirectToAction("Index");
			}

			product.ProductAmountUnitSelectListItems =
				_handlerProductAmountUnit.ReadAll()
												.ToSelectListItems(amountUnit => amountUnit.Name,
																   amountUnit => amountUnit.Id.ToString(),
																   amountUnit => amountUnit.Id == product.AmountUnitId);
			product.ProductQuantityUnitSelectListItems =
				_handlerProductQuantityUnit.ReadAll()
												  .ToSelectListItems(quantityUnit => quantityUnit.Name,
																	 quantityUnit => quantityUnit.Id.ToString(),
																	 quantityUnit =>
																	 quantityUnit.Id == product.QuantityUnitId);
			product.ProductCategorySelectListItems =
				_handlerProductCategory.ReadAll()
											  .ToSelectListItems(category => category.Name,
																 category => category.Id.ToString(),
																 category => category.Id == product.CategoryId);
			product.ProductManufacfurerSelectListItems =
				_handlerProductManufacturer.ReadAll()
												  .ToSelectListItems(manufacturer => manufacturer.Name,
																	 manufacturer => manufacturer.Id.ToString(),
																	 manufacturer => manufacturer.Id == product.ProductManufacturerId);

			return View(product);
		}

		// GET: /Product/Edit/5
		public ActionResult Edit(Guid? id)
		{
			if (id == null)
			{
				return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
			}
			var product = _handler.ReadOne(id.Value);
			if (product == null)
			{
				return HttpNotFound();
			}
			product.ProductAmountUnitSelectListItems =
				_handlerProductAmountUnit.ReadAll()
												.ToSelectListItems(amountUnit => amountUnit.Name,
																   amountUnit => amountUnit.Id.ToString(),
																   amountUnit => amountUnit.Id == product.AmountUnitId);
			product.ProductQuantityUnitSelectListItems =
				_handlerProductQuantityUnit.ReadAll()
												  .ToSelectListItems(quantityUnit => quantityUnit.Name,
																	 quantityUnit => quantityUnit.Id.ToString(),
																	 quantityUnit =>
																	 quantityUnit.Id == product.QuantityUnitId);
			product.ProductCategorySelectListItems =
				_handlerProductCategory.ReadAll()
											  .ToSelectListItems(category => category.Name,
																 category => category.Id.ToString(),
																 category => category.Id == product.CategoryId);
			product.ProductManufacfurerSelectListItems =
				_handlerProductManufacturer.ReadAll()
												  .ToSelectListItems(manufacturer => manufacturer.Name,
																	 manufacturer => manufacturer.Id.ToString(),
																	 manufacturer => manufacturer.Id == product.ProductManufacturerId);
			return View(product);
		}

		// POST: /Product/Edit/5
		// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
		// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
		[HttpPost]
		[ValidateAntiForgeryToken]
		public ActionResult Edit([Bind(Include = "Id,IsActive,DateAdded,DateUpdated,Name,ProductManufacturerId,CategoryId,Amount,AmountUnitId,Quantity,QuantityUnitId")] Product product)
		{
			if (!ModelState.IsValid) return View(product);

			if (_handler.Update(ref product) == ServiceResultEnum.Success)
			{
				return RedirectToAction("Index");
			}

			product.ProductAmountUnitSelectListItems =
				_handlerProductAmountUnit.ReadAll()
												.ToSelectListItems(amountUnit => amountUnit.Name,
																   amountUnit => amountUnit.Id.ToString(),
																   amountUnit => amountUnit.Id == product.AmountUnitId);
			product.ProductQuantityUnitSelectListItems =
				_handlerProductQuantityUnit.ReadAll()
												  .ToSelectListItems(quantityUnit => quantityUnit.Name,
																	 quantityUnit => quantityUnit.Id.ToString(),
																	 quantityUnit =>
																	 quantityUnit.Id == product.QuantityUnitId);
			product.ProductCategorySelectListItems =
				_handlerProductCategory.ReadAll()
											  .ToSelectListItems(category => category.Name,
																 category => category.Id.ToString(),
																 category => category.Id == product.CategoryId);
			product.ProductManufacfurerSelectListItems =
				_handlerProductManufacturer.ReadAll()
												  .ToSelectListItems(manufacturer => manufacturer.Name,
																	 manufacturer => manufacturer.Id.ToString(),
																	 manufacturer => manufacturer.Id == product.ProductManufacturerId);
			return View(product);
		}

		// GET: /Product/Delete/5
		public ActionResult Delete(Guid? id)
		{
			if (id == null)
			{
				return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
			}
			var product = _handler.ReadOne(id.Value);
			if (product == null)
			{
				return HttpNotFound();
			}
			return View(product);
		}

		// POST: /Product/Delete/5
		[HttpPost, ActionName("Delete")]
		[ValidateAntiForgeryToken]
		public ActionResult DeleteConfirmed(Guid id)
		{
			if (_handler.Delete(id) == ServiceResultEnum.Success)
			{
				return RedirectToAction("Index");
			}
			return View(_handler.ReadOne(id));
		}
	}
}
